home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-01-16 | 10.8 KB | 389 lines | [TEXT/PJMM] |
- {****************************************************}
- {}
- { CShAppLevelsDirector.p }
- {}
- { Director class for reading in the default levels. Reads the levels from the }
- { application resource, and the best players from the preferences file. }
- {}
- { Although nominally this is a responsibility of the application, because we }
- { draw a progress dialog, we need a separate director. This also brings us into }
- { line with the CShLevelsDoc, in that a separate object reads the levels and }
- { sends them to the game director. }
- {}
- {****************************************************}
-
-
- unit CShAppLevelsDirector;
-
- interface
-
- uses
- TCL, ShIntf;
-
- implementation
-
- type
- IntegerH = ^IntegerPtr;
-
- const
- kSTRAppDefaultLevels = 2;
-
- {****************************************************}
- {}
- { IShAppLevelsDirector }
- {}
- { Construction of the application levels reader object. }
- {}
- {****************************************************}
-
- procedure CShAppLevelsDirector.IShAppLevelsDirector (aSupervisor: CShApp;
- aAppResFile: Integer);
-
- begin { IShAppLevelsDirector }
- itsShApp := aSupervisor;
- itsProgBar := nil;
-
- IDirector(aSupervisor);
-
- itsAppResFile := aAppResFile;
- end; { IShAppLevelsDirector }
-
-
- {****************************************************}
- {}
- { Free }
- {}
- { Destruction of the application levels reader object. We set our pointers }
- { to nil, for the objects to which they were pointing will be disposed of in }
- { inherited methods. }
- {}
- {****************************************************}
-
- procedure CShAppLevelsDirector.Free;
-
- begin { Free }
- { The window disposes of all the subviews when it is freed. }
- { For completeness, we set our pointers to nil. }
-
- itsShApp := nil;
- itsProgBar := nil;
-
- inherited Free;
- end; { Free }
-
-
- {****************************************************}
- {}
- { BuildWindow }
- {}
- { Builds the window of the reader. }
- {}
- {****************************************************}
-
- procedure CShAppLevelsDirector.BuildWindow;
-
- var
- theWindow: CWindow;
- theWindRect: Rect;
-
- thePicture: CPicture;
-
- theReadingStr, theDefaultStr: Str255;
- theEditText: CEditText;
-
- theProgBar: CProgressBar;
-
- theBorder: CPaneBorder;
-
- begin { BuildWindow }
- new(theWindow);
- theWindow.IWindow(WINDReader, kNotFloating, gDesktop, SELF);
- itsWindow := theWindow;
-
- { We don't want the window to be re-sizable. }
-
- SetRect(theWindRect, kReaderWindh, kReaderWindv, kReaderWindh, kReaderWindv);
- itsWindow.SetSizeRect(theWindRect);
-
- { Uses the same window as the documents ie non-modal. }
-
- itsWindow.SetModal(kModeless);
-
- gDecorator.PlaceNewWindow(itsWindow);
- gDecorator.CenterWindow(itsWindow);
-
- { Background picture. }
-
- new(thePicture);
- thePicture.IPicture(itsWindow, SELF, kReaderWindh, kReaderWindv, 0, 0, sizFIXEDSTICKY, sizFIXEDSTICKY);
- if gSystem.hasColorQD then begin
- thePicture.UsePICT(PICTReaderColour);
- end { if }
- else begin
- thePicture.UsePICT(PICTReaderBW);
- end; { else }
- thePicture.SetScaled(FALSE);
-
- { Text saying that we are reading the default levels. }
-
- new(theEditText);
- theEditText.IEditText(itsWindow, SELF, kReaderTextLenh, kReaderTextLenv, kReaderTextPosh, kReaderTextPosv, sizFIXEDSTICKY, sizFIXEDSTICKY, kReaderTextLenh);
- theEditText.Specify(kNotEditable, kNotSelectable, kNotStylable);
- theEditText.SetAlignCmd(cmdAlignLeft);
- theEditText.SetFontNumber(0); { System font, Chicago. }
- GetIndString(theReadingStr, STRlistAppMessages, kSTRAppReading);
- GetIndString(theDefaultStr, STRlistAppMessages, kSTRAppDefaultLevels);
- theEditText.SetTextString(Concat(theReadingStr, ' ', theDefaultStr, '.'));
-
- { Progress bar. }
-
- new(theProgBar);
- theProgBar.IProgressBar(itsWindow, SELF, kReaderProgBarLenh, kReaderProgBarLenv, kReaderProgBarPosh, kReaderProgBarPosv, sizFIXEDSTICKY, sizFIXEDSTICKY, kUseColor, kHorizontal, KNoShadow, FinderFillColor, FinderBackColor);
- itsProgBar := theProgBar;
-
- { Border for the progress bar. }
-
- new(theBorder);
- theBorder.IPaneBorder(kBorderFrame);
- theProgBar.SetBorder(theBorder);
- end; { BuildWindow }
-
-
- {****************************************************}
- {}
- { AppLevels }
- {}
- { Returns the list of application levels, with best players as they exist. }
- { Updates the progress bar whilst doing so. }
- {}
- {****************************************************}
-
- function CShAppLevelsDirector.AppLevels: CList;
-
- var
- theDefLevels: CList;
-
- theBestPlayers: BestArrayHand;
- theNumBestH: IntegerH;
-
- theLevel: CShLevel;
-
- theCount, theNumLevels: Integer;
- theBestCount, theCurrBestLevel, theBestMax: Integer;
-
- theSavedRes: Integer;
-
- begin { AppLevels }
- { Select the window to bring it to the front. }
-
- itsWindow.Select;
-
- { Until now, now updating has been done. }
- { We have to force one now, to correctly draw the picture. }
-
- itsWindow.Update;
-
- new(theDefLevels);
- theDefLevels.IList;
-
- { Get the array of best players from the preference file. }
-
- itsShApp.PreferencesFile.GetPref(kPrefBestPlayers, Handle(theBestPlayers));
- itsShApp.PreferencesFile.GetPref(kPrefNumBest, Handle(theNumBestH));
-
- { Number of best players. }
-
- if (theBestPlayers <> nil) and (theNumBestH <> nil) then begin
- theBestMax := theNumBestH^^;
- end { if }
- else begin
- theBestPlayers := nil;
- theBestMax := 0;
- end; { else }
-
- theBestCount := 1;
- if theBestMax >= 1 then begin
- {$PUSH}
- {$R-}
- theCurrBestLevel := theBestPlayers^^[1].theLevelNum;
- {$POP}
- end; { if }
-
- { Set the initial progress, resetting from any previous run. }
-
- itsProgBar.UpdateProgress(0);
-
- { Read each level from application resource, and place in list. }
-
- theSavedRes := CurResFile;
-
- UseResFile(itsAppResFile);
-
- theNumLevels := Count1Resources(kLEVLResType);
- for theCount := 1 to theNumLevels do begin
-
- { We are now reading resources from the application resource file. }
-
- new(theLevel);
- theLevel.SetLEVL(LEVLDefStart + theCount - 1);
-
- { If a corresponding record exists in the best player handle, use it. }
-
- if (theBestCount <= theBestMax) & (theCount = theCurrBestLevel) then begin
- {$PUSH}
- {$R-}
- with theBestPlayers^^[theBestCount] do begin
- theLevel.SetPlayer(thePlayer);
- theLevel.SetMoves(theMoves);
- theLevel.SetTime(theTime);
-
- theBestCount := theBestCount + 1;
-
- if theBestMax >= theBestCount then begin
- theCurrBestLevel := theBestPlayers^^[theBestCount].theLevelNum;
- end; { if }
- end; { with }
- {$POP}
- end { if }
- else begin
- theLevel.SetDefaultBestPlayer;
- end; { else }
-
- theDefLevels.InsertAt(theLevel, theCount);
-
- itsProgBar.UpdateProgress(Integer(LongInt(theCount) * 100 div theNumLevels));
-
- end;
-
- UseResFile(theSavedRes);
-
- { Finished with the handle. }
- theBestPlayers := nil;
-
- AppLevels := theDefLevels;
- end; { AppLevels }
-
-
- {****************************************************}
- {}
- { StoreBestPlayer }
- {}
- { Stores the specified best player to the preferences file. }
- {}
- {****************************************************}
-
- procedure CShAppLevelsDirector.StoreBestPlayer (aLevelNum: LevelsRange;
- aPlayer: Str15;
- aMoves: Integer;
- aTime: LongInt);
-
- var
- theBestPlayers, theNewBestPlayers: BestArrayHand;
- theNumBestH: IntegerH;
-
- theBestCount, theBestMax: Integer;
- isPresent: Boolean;
-
- begin { StoreBestPlayer }
- theNewBestPlayers := nil;
-
- itsShApp.PreferencesFile.GetPref(kPrefBestPlayers, Handle(theBestPlayers));
- itsShApp.PreferencesFile.GetPref(kPrefNumBest, Handle(theNumBestH));
-
- { Number of best players. }
-
- if (theBestPlayers = nil) or (theNumBestH = nil) then begin
- theBestPlayers := nil;
- theNumBestH := nil;
- theBestMax := 0;
- end { if }
- else begin
- theBestMax := theNumBestH^^;
- end; { else }
-
- { Scan through the array to see if aLevelNum already has a record. }
- { If so, then use HandToHand to copy the current preference handle }
- { otherwise create a new one with an additional entry. }
- { If there is a failure here, there is nothing to correct locally. We }
- { just allow the error to propagate. }
-
- isPresent := FALSE;
- theBestCount := 1;
- while (not isPresent) and (theBestCount <= theBestMax) do begin
- {$PUSH}
- {$R-}
- isPresent := theBestPlayers^^[theBestCount].theLevelNum = aLevelNum;
- {$POP}
-
- if not isPresent then begin
- theBestCount := theBestCount + 1;
- end; { if }
- end; { while }
-
- if isPresent then begin
- theNewBestPlayers := theBestPlayers;
-
- if HandToHand(Handle(theNewBestPlayers)) = noErr then begin
- {$PUSH}
- {$R-}
- theNewBestPlayers^^[theBestCount].thePlayer := aPlayer;
- theNewBestPlayers^^[theBestCount].theMoves := aMoves;
- theNewBestPlayers^^[theBestCount].theTime := aTime;
- {$POP}
-
- itsShApp.PreferencesFile.SetPref(kPrefBestPlayers, Handle(theNewBestPlayers));
- ForgetHandle(theNewBestPlayers);
- end; { if }
- end { if }
- else begin
-
- SetCriticalOperation(TRUE);
- theNewBestPlayers := BestArrayHand(NewHandleCanFail(SizeOf(BestPlayerRec) * (theBestMax + 1)));
- FailNIL(theNewBestPlayers);
- SetCriticalOperation(FALSE);
-
- { Scan through the levels, and copy them into place. }
-
- {$PUSH}
- {$R-}
- theBestCount := 1;
- while (theBestCount <= theBestMax) & (theBestPlayers^^[theBestCount].theLevelNum < aLevelNum) do begin
- theNewBestPlayers^^[theBestCount] := theBestPlayers^^[theBestCount];
- theBestCount := theBestCount + 1;
- end; { while }
-
- theNewBestPlayers^^[theBestCount].theLevelNum := aLevelNum;
- theNewBestPlayers^^[theBestCount].thePlayer := aPlayer;
- theNewBestPlayers^^[theBestCount].theMoves := aMoves;
- theNewBestPlayers^^[theBestCount].theTime := aTime;
-
- while (theBestCount <= theBestMax) do begin
- theNewBestPlayers^^[theBestCount + 1] := theBestPlayers^^[theBestCount];
- theBestCount := theBestCount + 1;
- end; { while }
- {$POP}
-
- itsShApp.PreferencesFile.SetPref(kPrefBestPlayers, Handle(theNewBestPlayers));
- ForgetHandle(theNewBestPlayers);
-
- if theNumBestH = nil then begin
- SetCriticalOperation(TRUE);
- theNumBestH := IntegerH(NewHandleCanFail(SizeOf(Integer)));
- FailNIL(theNumBestH);
- SetCriticalOperation(FALSE);
-
- theNumBestH^^ := 1;
- itsShApp.PreferencesFile.SetPref(kPrefNumBest, Handle(theNumBestH));
- ForgetHandle(theNumBestH);
- end { end }
- else if HandToHand(Handle(theNumBestH)) = noErr then begin
- theNumBestH^^ := theNumBestH^^ + 1;
- itsShApp.PreferencesFile.SetPref(kPrefNumBest, Handle(theNumBestH));
- ForgetHandle(theNumBestH);
- end; { else if }
- end; { else }
-
- end; { StoreBestPlayer }
-
-
- end. { CShAppLevelsDirector }